home *** CD-ROM | disk | FTP | other *** search
/ WINMX Assorted Textfiles / Ebooks.tar / Text - Tech - Electronics - Schematics - DS1820 - Thermometer and Thermostat (HTML TXT).zip / D1820.BS2 next >
Text File  |  1996-03-12  |  12KB  |  412 lines

  1. ' Dallas 1820 Thermometer Demo Program for the STAMP II
  2.  
  3. ' Dan Clemmensen, 20 Jan 96
  4. ' hhtp://www.shirenet.com/~dgc
  5. ' dgc@shirenet.com
  6. ' (703) 759-2686
  7. '
  8. ' This demo program reads inputs from multiple Dallas 1820 thermometers
  9. ' and displays the temperatures. It permits the user to add and remove
  10. ' thermometers, set software thermostat limits, and control output
  11. ' pins based on the thermostat limits.
  12. '
  13. ' Hardware:
  14. '   STAMP II, LCD serial backpack, four buttons, and a one-wire
  15. ' interface circuit.
  16. '
  17. ' The one-wire interface circuit consists of three cheap IC's and
  18. ' is described in detail at the above web site. The circuit is
  19. ' connected to the STAMP by two pins, one for input and one for output.
  20. ' The circuit also connects to a multidropped string of Dallas 1820
  21. ' thermometer IC's. The circuit and software do not permit "parasite
  22. ' power" operation of the 1820's, but the use of an additonal pin and
  23. ' slight modification to the hardware and software would allow "parasite
  24. ' power" operation.
  25. '
  26. ' The program consists of the bit-level and byte-level utilities
  27. ' for the thermometer and routines to issue the "read temp"  and 
  28. ' "read rom" sequence for a particular thermometer and retrieve
  29. ' the results.
  30. '
  31. ' A main loop reads the buttons to interpret user commands, and
  32. ' calls the command handlers.
  33. '
  34. ' Button 1 is a "change mode" command. 
  35. ' Modes 0-n are to control thermometers 0 thru n. 
  36. ' Mode n+1 is "add thermometer".
  37. ' Mode n+1 is "run" mode,
  38. ' Control modes (one per thermometer): button 2  cycles thru the control
  39. ' submodes. change therm id, delete, inc temp, dec temp, inc range,
  40. ' dec range, change relay. 
  41. ' When in a submode, button 3 is the execute.
  42. '
  43. ' RUN mode: continuously get temperatures from all thermometers, and
  44. ' display them
  45. '
  46. ' Output messages are sent to the LCD BACKPACK using the SEROUT command
  47. ' as in the LCD documentation.
  48.  
  49. '------------------------------------------
  50. ' Variable and Constant declaration section
  51. '------------------------------------------
  52. ' --- I/O value aliases. The four buttons are readable via
  53. ' the preassigned variables in8, in9, in10, and in11, or collectively
  54. ' via the nibble variable named 'inc'.
  55.  
  56. button4val  VAR in8  
  57. button3val  VAR in9
  58. button2val  VAR in10  
  59. button1val  VAR in11 
  60. buttonvals  VAR inc
  61. button1mask CON $8
  62. button2mask CON $4
  63. button3mask CON $2
  64. pbuttonvals VAR nib  ' prior value of buttons
  65. '
  66. ' -- Constants and variables associated with the LCD backpack.
  67. '
  68. '
  69. lcdpin        CON 4
  70. N2400         CON 396+$4000   'param for SEROUT: 2400, 8-bit, no parity,invert
  71. lcdinst       CON 254
  72. lcdclr        CON 1
  73. '
  74. ' -- Constants and variables associated with the one-wire interface
  75. '    circuit and bit-level protocol
  76. '
  77. stamp_pulse   CON 2              'pulsout has a 2 us granularity
  78. thermoutpin   CON 7          
  79. thermin       VAR in6
  80. thermresetlen CON 600/stamp_pulse
  81. thermwr0len   CON 60/stamp_pulse
  82. thermwr1len   CON 1               'should be 1us, but 2 will work
  83. '
  84. ' -- Constants and variables associated with the byte-level
  85. ' protocol
  86. '
  87. bytecnt   VAR nib
  88. work      VAR byte
  89. tbyte     VAR byte
  90. crcbyte   VAR byte
  91. crcbit    VAR bit
  92. '
  93. ' Buffer for storage of the responses from the thermometers
  94. ' The buffer is 10 bytes. It is defined for both byte and word
  95. ' usage.
  96. '
  97. tempbuffw     VAR word(5)
  98. tempbuff      VAR tempbuffw.byte0
  99. '
  100. ' variables and constants associated with program control
  101. '
  102. mode      VAR byte     'current operating mode.
  103. submode   VAR nib      'current submode
  104. max_submode   CON 7
  105. '
  106. ' -- Constants, variables, and data associated with the ID array.
  107. ' The array is maintained in the DATA area of the STAMP EEPROM. There is 
  108. ' an entry for each thermometer. Each entry is 11 bytes long, and contains
  109. ' the 8-byte ROM id and three thermostat parameters: the temperature, the 
  110. ' range, and the relay mask. Note that the data is not initialized by this
  111. ' source file. Instead, the user uses the "Change" command to add thermometers
  112. ' and thermostat settings.
  113. ' Since the STAMP download preserves uninitialized data, this program may be
  114. ' modified and reloaded into the STAMP without affecting the IDs that were
  115. ' stored earlier, as long as no additional DATA is declared.
  116. '
  117. idcnt     VAR byte
  118. id_max    VAR byte
  119. id_entry_len CON 11
  120. temp_offset  CON 8
  121. range_offset CON 9
  122. relay_offset CON 10
  123. nbr_of_ids   DATA (1)               'highest device num
  124. idarray      DATA (11)              'first ID
  125. '
  126. '------------------------------------------------
  127. ' Main Program.
  128. '------------------------------------------------
  129. '
  130. 'initialization
  131. '  set the output pin to output a 1 as the default. This causes the PULSOUT
  132. '  commands to send negative-going pulses. Move the number of thermometers
  133. '  into working storage
  134. '
  135.    HIGH thermoutpin
  136.    READ nbr_of_ids,id_max
  137.    mode=id_max+1
  138. '
  139. ' Main loop. This is an endless loop that samples the buttons for a
  140. ' command. When a command is read, it is executed. If no command is detected,
  141. ' the program executes the display for the current mode.
  142. '
  143. main_loop:
  144.    IF buttonvals=pbuttonvals THEN nochange
  145.    GOSUB buttonchange
  146. nochange:
  147.    IF mode=id_max+1 THEN call_temp
  148.    GOSUB therm_mode
  149.    GOTO main_loop
  150. call_temp:
  151.    GOSUB temp_display
  152.    GOTO main_loop
  153. '
  154. '------------------------------------------------
  155. ' Process one of the thermometer modes.
  156. '------------------------------------------------
  157. '
  158. therm_mode:
  159.    GOSUB rom_display
  160.    RETURN
  161. '
  162. '------------------------------------------------
  163. ' Subroutine to check for button input and change the mode
  164. ' accordingly.
  165. '------------------------------------------------
  166. '
  167. buttonchange:
  168. depress VAR work
  169.    depress=(pbuttonvals) & (~buttonvals)
  170.    pbuttonvals=buttonvals
  171.    IF depress&button1mask THEN modechange
  172.    IF depress&button2mask THEN submodechange
  173.    IF depress&button3mask THEN execute
  174.    RETURN
  175. modechange:
  176.    mode=(mode+1)//(id_max+2)
  177.    submode=0
  178.    RETURN
  179. submodechange:
  180.    IF mode>id_max THEN no_submode
  181.    submode=(submode+1)//max_submode
  182. no_submode:
  183.    RETURN
  184. execute:
  185.    BRANCH submode,[change_id, delete_id, inc_temp, dec_temp, inc_range,dec_range, change_relay]
  186.    RETURN
  187. change_id:
  188.    GOSUB romread
  189.    IF crcbyte<>0 THEN no_change
  190.    FOR bytecnt=0 TO 7
  191.      WRITE idarray+(id_entry_len*idcnt)+bytecnt,tempbuff(bytecnt)
  192.    NEXT
  193.    IF mode<id_max THEN no_change
  194.    id_max=id_max+1
  195.    WRITE nbr_of_ids,id_max
  196. no_change:
  197.    RETURN
  198. delete_id:
  199.    WRITE idarray+(id_entry_len*idcnt),0
  200.    RETURN
  201. inc_temp:
  202.    READ idarray+(id_entry_len*idcnt)+temp_offset,work
  203.    work=work+1
  204.    write idarray+(id_entry_len*idcnt)+temp_offset,work
  205.    RETURN
  206. dec_temp:
  207.    READ idarray+(id_entry_len*idcnt)+temp_offset,work
  208.    work=work-1
  209.    write idarray+(id_entry_len*idcnt)+temp_offset,work
  210.    RETURN
  211. inc_range:
  212.    READ idarray+(id_entry_len*idcnt)+range_offset,work
  213.    work=work+1
  214.    write idarray+(id_entry_len*idcnt)+range_offset,work
  215.    RETURN
  216. dec_range:
  217.    READ idarray+(id_entry_len*idcnt)+range_offset,work
  218.    work=work-1
  219.    write idarray+(id_entry_len*idcnt)+range_offset,work
  220.    RETURN
  221. change_relay:
  222.    RETURN
  223. '
  224. '------------------------------------------------
  225. ' Subroutine to read the temperature of
  226. ' each thermometer in the list, compute the faranheit temp, and display
  227. ' the result.
  228. '------------------------------------------------
  229. '
  230. temp_display:
  231.    GOSUB tempcvt
  232.    FOR idcnt= 0 TO id_max
  233.      GOSUB tempread
  234.      DEBUG "T",dec idcnt,":"
  235.      GOSUB faren
  236.      DEBUG dec tempbuffw(2)/100+32,".", dec2 tempbuffw(2)//100
  237. '     FOR work=0 TO 8
  238. '       DEBUG hex tempbuff(work)," "
  239. '     NEXT 
  240.      DEBUG CR
  241.    NEXT
  242.    RETURN
  243. '
  244. '------------------------------------------------
  245. 'Subroutine to read the rom-id of a single 1820 and display it.
  246. '------------------------------------------------
  247. '
  248. rom_display:
  249.    GOSUB romread
  250.    FOR work=0 TO 7
  251.      DEBUG hex tempbuff(work)," "
  252.    NEXT 
  253.    DEBUG CR
  254.    RETURN
  255. '
  256. '------------------------------------------------
  257. ' romread
  258. ' issue a romread command and read the response
  259. '------------------------------------------------
  260. '
  261. romread:
  262.   GOSUB treset
  263.   tbyte=$33
  264.   GOSUB twrbyte
  265.   crcbyte=0
  266.   FOR bytecnt=0 TO 7
  267.     GOSUB trdbyte
  268.     tempbuff(bytecnt)=tbyte
  269.   NEXT
  270.   IF crcbyte=0 THEN romread_ok
  271.   DEBUG "BAD CRC!", CR
  272. romread_ok:
  273.   RETURN
  274. '------------------------------------------------
  275. ' tempcvt. Issue a convert command to all of the
  276. ' 1820's at once. 
  277. '------------------------------------------------
  278. '
  279. tempcvt:
  280.   GOSUB treset
  281.   tbyte=$CC          'skip ROM (i.e., address the command to all devices)
  282.   GOSUB twrbyte
  283.   tbyte=$44          ' convert (i.e., sense and store the temperature)
  284.   GOSUB twrbyte
  285.   PAUSE 500          ' conversion can take up to .5 sec. 
  286.   RETURN
  287. '------------------------------------------------
  288. ' tempread.  read the temperature data from a particular
  289. ' 1820
  290. '------------------------------------------------
  291. '
  292. tempread:
  293.   GOSUB treset
  294.   GOSUB sendid
  295.   tbyte=$BE
  296.   GOSUB twrbyte
  297.   crcbyte=0
  298.   FOR bytecnt=0 TO 8
  299.     GOSUB trdbyte
  300.     tempbuff(bytecnt)=tbyte
  301.   NEXT
  302.   IF crcbyte=0 THEN crc_ok
  303.     DEBUG "bad CRC!",CR
  304. crc_ok:
  305.   RETURN
  306. '
  307. '------------------------------------------------
  308. 'sendid. send the ID string of the device number given in idcnt
  309. '------------------------------------------------
  310. '
  311. sendid:
  312.   tbyte=$55
  313.   GOSUB twrbyte
  314.   FOR bytecnt=0 TO 7
  315.     READ idarray+(8*idcnt)+bytecnt,tbyte
  316.     GOSUB twrbyte
  317.   NEXT
  318.   RETURN
  319. '
  320. '------------------------------------------------
  321. 'trdbyte. Read 8 bits into tbyte
  322. '------------------------------------------------
  323. '
  324. trdbyte:
  325.   FOR work=0 TO 7
  326.     GOSUB trdbit
  327.     tbyte.bit0(work)=thermin
  328.     crcbit=crcbyte.bit0^thermin
  329.     crcbyte=(crcbyte>>1)
  330.     crcbyte.bit7=crcbit
  331.     crcbyte.bit2=crcbyte.bit2^crcbit
  332.     crcbyte.bit3=crcbyte.bit3^crcbit
  333.   NEXT
  334.   RETURN
  335. '
  336. '------------------------------------------------
  337. 'twrbyte.   write (i.e., send) the 8 bits from tbyte
  338. '------------------------------------------------
  339. '
  340. twrbyte:
  341.   FOR work=0 TO 7
  342.     IF tbyte.bit0(work)=0 THEN twr0
  343.     GOSUB twrbit1
  344.     GOTO twrbytenext
  345.   twr0:
  346.     GOSUB twrbit0
  347.   twrbytenext:
  348.     NEXT
  349.   RETURN
  350. '
  351. '------------------------------------------------
  352. 'treset. send a reset pulse. wait one ms for the "presence" responses
  353. ' to die down.
  354. '------------------------------------------------
  355. '
  356. treset:
  357.   PULSOUT thermoutpin,thermresetlen
  358.   PAUSE 1
  359.   RETURN
  360. '
  361. '------------------------------------------------
  362. 'trdbit. Read one bit. response will be in thermin. Note that
  363. ' this routine is simply another name for twrbit1!  The only difference
  364. ' is in the mind of the programmer.
  365. '------------------------------------------------
  366. '
  367. trdbit:
  368. '
  369. '------------------------------------------------
  370. 'twrbit1.
  371. '   write (send) a one bit.
  372. '------------------------------------------------
  373. '
  374. twrbit1:
  375.   PULSOUT thermoutpin,thermwr1len
  376.   RETURN
  377. '
  378. '------------------------------------------------
  379. 'twrbit0.
  380. ' write (send) zero bit.
  381. '------------------------------------------------
  382. '
  383. twrbit0:
  384.   PULSOUT thermoutpin,thermwr0len
  385.   RETURN 
  386.  
  387. '
  388. '------------------------------------------------
  389. ' faren. This routine converts the thermometer input to
  390. ' degrees and tenths "biased" farenheit. (Actually, returns hundredths,
  391. ' but the true precision isn't this high.) input is in the
  392. ' temp buff. output is to the "reserved word" in the temp buff,
  393. ' treated as a 16-bit word named tempbuffw(2).
  394. ' The result is biased by 32 degrees farenheit. Add 32 degrees to get
  395. ' actual farenheit.
  396. '
  397. ' The 1820 returns Centigrade whole degreees, plus
  398. ' a max count and remaining count for the current degree.
  399. ' The hi-res temp is computed as : hi_res=lo_res+.75-remain/max.
  400. ' The result is converted to farenheit by multiplying by 1.8 and
  401. ' adding 32.
  402. ' This routine uses 16-bit integer arithmetic, we convert to hundredths
  403. ' of a farenheit degree first: f_lores_100ths=lo_res*180, then add the .75C:
  404. ' +135. Now we have to subtract the correction factor: -180*remain/max.
  405. '------------------------------------------------
  406. '  
  407. faren:
  408.   tempbuffw(2)=(tempbuffw(0)>>1)*180+135 - (180*tempbuff(6)/tempbuff(7))
  409.   RETURN
  410.